/*
  S.M.A.C.K - An operating system kernel
  Copyright (C) 2010,2011 Mattias Holm and Kristian Rietveld
  For licensing and a full list of authors of the kernel, see the files
  COPYING and AUTHORS.
*/

#include <stdint.h>
#include <stddef.h>
#include <vm.h>

/* Currently we only specify WKUP_CM and DSS_CM, there are the only
 * we need so far.
 */
struct omap_cm
{
  uint32_t padding[3072/4];

  /* WKUP_CM */
  uint32_t cm_fclken_wkup;
  uint32_t padding0[3];
  uint32_t cm_iclken_wkup;
  uint32_t padding1[3];
  uint32_t cm_idlest_wkup;
  uint32_t padding2[3];
  uint32_t cm_autoidle_wkup;
  uint32_t padding3[3];
  uint32_t cm_clksel_wkup;

  uint32_t padding4[444/4];

  /* DSS_CM */
  uint32_t cm_fclken_dss;
  uint32_t padding5[3];
  uint32_t cm_iclken_dss;
  uint32_t padding6[3];
  uint32_t cm_idlest_dss;
  uint32_t padding7[3];
  uint32_t cm_autoidle_dss;
  uint32_t padding8[3];
  uint32_t cm_clksel_dss;
  uint32_t cm_sleepdep_dss;
  uint32_t cm_clkstctrl_dss;
  uint32_t cm_clkstst_dss;
};

static volatile struct omap_cm *omap_cm;

#define CM_FCLKEN_WKUP_EN_GPT1 0
#define CM_CLKSEL_WKUP_CLKSEL_GPT1 0
#define CM_AUTOIDLE_WKUP_AUTO_GPT1 0

#define CM_FCLKEN_DSS_EN_DSS1 0
#define CM_FCLKEN_DSS_EN_DSS2 1
#define CM_FCLKEN_DSS_EN_TV 2
#define CM_ICLKEN_DSS_EN_DSS 1

void
omap_clock_enable_dss_clocks (void)
{
  omap_cm->cm_fclken_dss |= 1 << CM_FCLKEN_DSS_EN_DSS1;
  omap_cm->cm_iclken_dss |= 1 << CM_ICLKEN_DSS_EN_DSS;
}

void
omap_clock_enable_gpt1 (void)
{
  /* Make sure functional clock for GPT1 is enabled */
  omap_cm->cm_fclken_wkup |= 1 << CM_FCLKEN_WKUP_EN_GPT1;

  /* Select 32KHz clock as source */
  omap_cm->cm_clksel_wkup &= ~(1 << CM_CLKSEL_WKUP_CLKSEL_GPT1);
}

void
omap_clock_init (void)
{
  omap_cm = vm_map_physical(vm_get_kernel_map(VM_REG_DEVICE), VM_DEVICE | VM_SUPER_RW,
                            (uintptr_t)0x48004000, 4096);

}
